package com.huilian.iotbox.data.service.impl;

import com.alibaba.fastjson.JSON;
import com.huilian.iotbox.data.service.RetryService;
import com.huilian.iotbox.data.common.ServerResponse;
import com.huilian.iotbox.data.enums.MqttReplyQueryResultCodeEnum;
import com.huilian.iotbox.data.utils.DateTimeUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.retry.annotation.Backoff;
import org.springframework.retry.annotation.Recover;
import org.springframework.retry.annotation.Retryable;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import java.io.Serializable;

/**
 * spring-retry重试接口
 */
@Slf4j
@Service
public class RetryServiceImpl implements RetryService {

    @Autowired
    private RedisTemplate<String, Serializable> redisCacheTemplate;

    @Retryable(value = RuntimeException.class, maxAttempts = 10, backoff = @Backoff(delay = 500))
    @Override
    public ServerResponse getCallBack(String redisKey, Integer deviceId, Integer cmdId, String mqttMessageBusinessId) {

        log.info("处理时间：" + DateTimeUtils.currTime());

        final String key = String.format(redisKey, deviceId, cmdId, mqttMessageBusinessId);
        log.info("key:" + key);
        final Serializable serializable = redisCacheTemplate.opsForValue().get(key);
        log.info("serializable:" + JSON.toJSONString(serializable));
        if (StringUtils.isEmpty(serializable)) {
            throw new RuntimeException("重试");
        }
        int r = (int) serializable;

        if (r == -1) {
            throw new RuntimeException("重试");
        }
        log.info("r:" + r);
        if (MqttReplyQueryResultCodeEnum.FAIL.getResultCode().compareTo(r) == 0) {
            // 处理失败
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.FAIL.getCode(), MqttReplyQueryResultCodeEnum.FAIL.getDesc());
        } else if (MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getResultCode().compareTo(r) == 0) {
            // 未知失败
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getCode(), MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getDesc());
        } else if (MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getResultCode().compareTo(r) == 0) {
            // 统一自定义结果
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getCode(), MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getDesc());
        }

        // 处理成功
        return ServerResponse.createBySuccess();
    }

    @Retryable(value = RuntimeException.class, maxAttempts = 20, backoff = @Backoff(delay = 500))
    @Override
    public ServerResponse getCallBackByQueryingTerminalStatus(String redisKey, Integer deviceId, Integer cmdId, String payNo) {

        log.info("处理时间：" + DateTimeUtils.currTime());

        final String key = String.format(redisKey, deviceId, cmdId, payNo);
        log.info("key:" + key);
        final Serializable serializable = redisCacheTemplate.opsForValue().get(key);
        log.info("serializable:" + JSON.toJSONString(serializable));
        if (StringUtils.isEmpty(serializable)) {
            throw new RuntimeException("重试");
        }
        int r = (int) serializable;

        if (r == -1) {
            throw new RuntimeException("重试");
        }
        log.info("r:" + r);
        if (MqttReplyQueryResultCodeEnum.FAIL.getResultCode().compareTo(r) == 0) {
            // 处理失败
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.FAIL.getCode(), MqttReplyQueryResultCodeEnum.FAIL.getDesc());
        } else if (MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getResultCode().compareTo(r) == 0) {
            // 未知失败
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getCode(), MqttReplyQueryResultCodeEnum.AN_UNKNOWN_FAILURE.getDesc());
        } else if (MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getResultCode().compareTo(r) == 0) {
            // 统一自定义结果
            return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getCode(), MqttReplyQueryResultCodeEnum.UNIFY_CUSTOM_RESULTS.getDesc());
        }

        // 处理成功
        return ServerResponse.createBySuccess();
    }

    /**
     * 重试完的兜底操作
     *
     * @param e
     */
    @Recover
    public ServerResponse recover(RuntimeException e) {
        log.error("重试完的兜底操作", e);
        return ServerResponse.createByErrorCodeMessage(MqttReplyQueryResultCodeEnum.NO_REPLY.getCode(), MqttReplyQueryResultCodeEnum.NO_REPLY.getDesc());
    }

}
